<template>
  <div class="view" v-loading="loading">
    <!-- 弹窗 -->
    <el-dialog
      :visible.sync="dialogVisible"
      :title="dialogTitle"
      :before-close="handleDialogClose"
      :close-on-click-modal="false"
      width="520px">
      <!-- 创建集群表单 -->
      <create-cluster
        v-if="dialogType === 'create' && dialogVisible"
        @click="handleDialogClose"
        :clusterNames="totalClusterNames"
        :ips="totalIps">
      </create-cluster>
      <!-- 添加已有集群表单 -->
      <add-cluster
        v-if="dialogType === 'add' && dialogVisible"
        @click="handleDialogClose">
      </add-cluster>
    </el-dialog>

    <div class="view-header">
      <div class="view-header_left">集群概览</div>
      <div class="view-header_right">
        <div class="view-header_right__search">
          <el-input
            type="text"
            v-model="searchName"
            placeholder="输入集群名称搜索"
            @input="handleSearchClusterName"
            clearable>
            <i slot="suffix" class="el-input__icon el-icon-search"></i>
          </el-input>
        </div>
        <div class="view-header_right__sort">
          <el-select v-model="sortData" @change="handleClusterSort">
            <el-option
              v-for="item in sortOption"
              :key="item.key"
              :label="item.name"
              :value="item.key">
            </el-option>
          </el-select>
        </div>
        <div class="view-header_right__btn">
          <el-button type="primary" @click="handleCreateCluster">创建集群</el-button>
          <el-button type="success" @click="handleAddCluster">添加已有集群</el-button>
          <el-button
            type="danger"
            @click="handleDestroyCluster"
            :disabled="checkSelectName.indexOf(true) < 0">
            摧毁集群
          </el-button>
          <el-button
            type="warning"
            @click="handleRemoveCluster"
            :disabled="checkSelectName.indexOf(true) < 0">
            移除集群
          </el-button>
        </div>
      </div>
    </div>
    <div class="view-content">
      <div v-if="clusterView.length === 0" class="view-content_none">
        <img src="/static/nodata.png" alt="png" />
        <p>您还没有集群，快去创建吧</p>
      </div>
      <div v-if="clusterView.length > 0" class="view-content_show">
        <el-col
          :span="12"
          class="view-card"
          v-for="(clusterItem, index) in clusterView"
          :key="clusterItem.cluster_name">
          <el-card>
            <div slot="header" class="card-header">
              <div class="card-header_text">
                <el-checkbox v-model="checkSelectName[index]" @change="handleCheckCluster">
                  <!-- 集群online为true或stop  可点击跳转到集群资源界面 -->
                  <span
                    style="color: green"
                    @click="handleClickHaName(clusterItem.cluster_name)"
                    v-if="
                      clusterItem.cluster_online === 'true' ||
                      clusterItem.cluster_online === true ||
                      clusterItem.cluster_online === 'stop'
                    ">
                    {{ clusterItem.cluster_name }}
                  </span>
                  <!-- 其他情况 集群名称为红色，不可跳转界面 -->
                  <span v-else style="color: red">{{ clusterItem.cluster_name }}</span>
                </el-checkbox>
              </div>
              <div>
                <span style="margin-right: 30px">节点数：{{ clusterItem.node_sum }}</span>
                <span>心跳数：{{ clusterItem.ip_num }}路</span>
              </div>
            </div>
            <div class="card-content">
              <div class="card-content-node">
                <p class="card-content-status-title">节点状态：</p>
                <div class="card-content-status">
                  <div
                    class="card-content-status-cnt"
                    v-for="node in clusterItem.node_status"
                    :key="node.name">
                    <p :style="{ color: node.color, 'font-weight': 600 }">{{ node.statusNum }}</p>
                    <p>{{ node.name }}</p>
                  </div>
                </div>
              </div>
              <div class="card-content-rsc">
                <p class="card-content-status-title">资源状态：</p>
                <div class="card-content-status">
                  <div
                    class="card-content-status-cnt"
                    v-for="rsc in clusterItem.rsc_status"
                    :key="rsc.name">
                    <p :style="{ color: rsc.color, 'font-weight': 600 }">{{ rsc.statusNum }}</p>
                    <p>{{ rsc.name }}</p>
                  </div>
                </div>
              </div>
            </div>
          </el-card>
        </el-col>
      </div>
    </div>
  </div>
</template>

<script>
import { getClusterView, destroyCluster, removeCluster } from '@/api/clusterOverview'
import CreateCluster from './form/createCluster.vue'
import AddCluster from './form/addCluster.vue'

export default {
  name: 'ClusterOverview',
  components: {
    CreateCluster,
    AddCluster,
  },
  data() {
    return {
      loading: false,
      clusterView: [], // 集群数据
      clusterBak: [], // 集群数据备份，用于排序和搜索
      checkSelectName: [], // 选择的集群的下标 true为选中，false为未选中
      localClusterName: '', // 本地集群
      totalIps: [], // 所有ip集合
      totalClusterNames: [], // 所有集群名称集合
      searchName: '', // 搜索关键字
      sortOption: [
        { key: '0', name: '默认排序' },
        { key: '1', name: '名称排序' },
        { key: '2', name: '错误记录排序' },
      ],
      sortData: '0', // 默认选择默认排序
      dialogVisible: false, // 弹窗显示控制
      dialogTitle: '', // 弹窗标题
      dialogType: '', // 弹窗类型：'create' 创建集群，'add' 添加已有集群
    }
  },
  created() {
    // 页面初始化逻辑
    this.clusterViewDataInit()
  },
  methods: {
    // 数据初始化
    clusterViewDataInit() {
      this.loading = true
      getClusterView()
        .then((res) => {
          this.loading = false
          if (res.data.action) {
            this.localClusterName = res.data.local_cluster_name
            const clusterData = res.data.cluster_data || []

            this.clusterView = []
            this.totalIps = []
            this.totalClusterNames = []

            // 默认按照名称排序
            clusterData.sort((a, b) => {
              return a.cluster_name.toLowerCase() > b.cluster_name.toLowerCase() ? 1 : -1
            })

            // 如果集群名称未设置，设置为本地集群
            if (!localStorage.getItem('clusterName')) {
              localStorage.setItem('clusterName', res.data.local_cluster_name)
            }

            // 处理集群数据
            if (clusterData.length === 0) {
              this.clusterView = []
              this.clusterBak = []
            } else {
              clusterData.forEach((clusterItem) => {
                // 获取所有集群名称
                this.totalClusterNames.push(clusterItem.cluster_name)

                // 处理ip 获取所有ip
                if (clusterItem.ip && clusterItem.ip.length > 0) {
                  clusterItem.ip.forEach((ipItem) => {
                    Object.keys(ipItem).forEach((addr) => {
                      this.totalIps.push(ipItem[addr])
                    })
                  })
                }

                const hb_num =
                  clusterItem.ip && clusterItem.ip.length > 0
                    ? Object.keys(clusterItem.ip[0].Addrs).length
                    : 0

                // 集群概览页面数据
                const statusInfo = this.handleClusterStatus(clusterItem)
                this.clusterView.push({
                  cluster_name: clusterItem.cluster_name,
                  cluster_online: clusterItem.cluster_online,
                  ip_num: hb_num,
                  node_sum: clusterItem.node_sum,
                  node_status: statusInfo.nodeInfo,
                  rsc_status: statusInfo.rscInfo,
                })
              })

              this.clusterBak = [...this.clusterView]
            }

            // 应用当前的排序
            this.sortClusterView(this.sortData)
          } else {
            this.$message.error(res.data.error || '获取集群数据失败')
          }
        })
        .catch((err) => {
          this.loading = false
          console.error('获取集群数据失败:', err)
        })
    },

    // 处理集群节点/资源状态（状态，数量）
    handleClusterStatus(clusterItem) {
      const nodeInfo = [
        { name: 'online', color: '#41c674', status: ['online'], statusNum: 0 },
        { name: 'offline', color: 'gray', status: ['offline'], statusNum: 0 },
      ]
      const rscInfo = [
        { name: '正常运行', color: '#41c674', status: ['Running'], statusNum: 0 },
        { name: '有错误记录', color: '#ffd500', status: ['Running but failed'], statusNum: 0 },
        { name: '运行失败', color: 'red', status: ['Stop'], statusNum: 0 },
        { name: '未启动', color: 'gray', status: ['Not Running', 'Unmanaged'], statusNum: 0 },
      ]

      // 处理节点状态
      if (clusterItem.node_list) {
        clusterItem.node_list.forEach((item) => {
          if (item.online === 'true' || item.online === true) {
            nodeInfo[0].statusNum++
          } else {
            nodeInfo[1].statusNum++
          }
        })
      }

      // 若离线数量是节点数量，则资源状态和节点online的数量展示为 -
      if (nodeInfo[1].statusNum !== clusterItem.node_list.length) {
        if (clusterItem.resource_list) {
          clusterItem.resource_list.forEach((item) => {
            rscInfo.forEach((rscItem) => {
              if (rscItem.status.indexOf(item.status) > -1) {
                rscItem.statusNum++
              }
            })
          })
        }
      } else {
        nodeInfo[0].statusNum = '-'
        rscInfo.forEach((item) => {
          item.statusNum = '-'
        })
      }

      return { nodeInfo, rscInfo }
    },

    // 点击集群名称，跳转到资源界面
    handleClickHaName(name) {
      localStorage.setItem('clusterName', name)
      this.$router.push('/resource')
    },

    // 选择集群名称
    handleCheckCluster(value) {
      console.log('handleCheckCluster', value, this.checkSelectName)
    },

    // 搜索集群名称
    handleSearchClusterName(value) {
      if (value) {
        this.clusterView = this.clusterBak.filter((item) => {
          return item.cluster_name.indexOf(value) > -1
        })
      } else {
        this.clusterView = [...this.clusterBak]
      }
    },

    // 集群排序
    handleClusterSort(value) {
      this.sortClusterView(value)
    },

    // 集群概览界面排序功能
    sortClusterView(value) {
      switch (value) {
        case '0':
          // 默认排序 - 恢复原始顺序
          this.clusterView = [...this.clusterBak]
          break
        case '1':
          // 名称排序 - 按集群名称字母顺序排序
          this.clusterView = this.clusterView.sort((a, b) => {
            return a.cluster_name.toLowerCase() > b.cluster_name.toLowerCase() ? 1 : -1
          })
          break
        case '2':
          // 错误记录排序 - 按有错误记录的资源数量降序排序
          this.clusterView = this.clusterView.sort((a, b) => {
            const runFailedA = a.rsc_status.filter((item) => item.name === '有错误记录')[0]
            const runFailedB = b.rsc_status.filter((item) => item.name === '有错误记录')[0]

            // 如果两个都是字符串（'-'），则不排序
            if (
              typeof runFailedA.statusNum === 'string' &&
              typeof runFailedB.statusNum === 'string'
            ) {
              return 0
            }

            // 如果A是字符串，则A排在后面
            if (typeof runFailedA.statusNum === 'string') {
              return 1
            }

            // 如果B是字符串，则B排在后面
            if (typeof runFailedB.statusNum === 'string') {
              return -1
            }

            // 按错误数量降序排序
            return runFailedA.statusNum >= runFailedB.statusNum ? -1 : 1
          })
          break
      }
    },

    // 创建集群
    handleCreateCluster() {
      this.dialogTitle = '创建集群'
      this.dialogType = 'create'
      this.dialogVisible = true
    },

    // 添加已有集群
    handleAddCluster() {
      this.dialogTitle = '添加已有集群'
      this.dialogType = 'add'
      this.dialogVisible = true
    },

    // 弹窗关闭
    handleDialogClose(type) {
      this.dialogVisible = false
      this.dialogTitle = ''
      this.dialogType = ''

      // 如果是创建或添加成功，刷新列表
      if (type === 'success') {
        this.clusterViewDataInit()
      }
    },

    // 摧毁集群
    handleDestroyCluster() {
      // 收集选中的集群名称
      const clusterNames = []
      this.checkSelectName.forEach((isSelected, index) => {
        if (isSelected) {
          clusterNames.push(this.clusterView[index].cluster_name)
        }
      })

      if (clusterNames.length === 0) {
        this.$message.warning('请先选择要摧毁的集群')
        return
      }

      // 显示确认对话框
      this.$confirm('是否摧毁该集群？', '提示', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
        closeOnClickModal: false,
        beforeClose: (action, instance, done) => {
          if (action === 'confirm') {
            // 开启按钮加载状态
            instance.confirmButtonLoading = true

            // 调用API
            destroyCluster({ cluster_name: clusterNames })
              .then((res) => {
                instance.confirmButtonLoading = false
                if (res.data.action) {
                  // 检查是否有失败的集群
                  if (res.data.clusters && res.data.clusters.length > 0) {
                    // 部分或全部失败
                    this.showDestroyErrorDialog(res.data.clusters, res.data.detailInfo)
                  } else {
                    // 全部成功
                    this.$message.success('集群摧毁成功！')
                  }
                } else {
                  this.$message.error(res.data.error || '集群摧毁失败！')
                }
                // 刷新列表
                this.clusterViewDataInit()
                // 清空选中状态
                this.checkSelectName = []
                done()
              })
              .catch((err) => {
                instance.confirmButtonLoading = false
                console.error('摧毁集群失败:', err)
                this.$message.error('集群摧毁失败！')
                done()
              })
          } else {
            done()
          }
        },
      }).catch(() => {
        // 用户取消操作
      })
    },

    // 显示摧毁集群失败详情对话框
    showDestroyErrorDialog(clusters, detailInfo) {
      // 构建错误信息HTML
      let errorHtml = '<div style="line-height: 1.8; max-height: 200px; overflow-y: auto; text-align: left;">'
      clusters.forEach((clusterName, index) => {
        errorHtml += `<p style="margin: 5px 0;"><strong>${clusterName}:</strong> ${detailInfo[index]}</p>`
      })
      errorHtml += '</div>'

      this.$alert(errorHtml, '摧毁集群失败', {
        confirmButtonText: '确认',
        type: 'error',
        dangerouslyUseHTMLString: true,
        closeOnClickModal: false,
      })
    },

    // 移除集群
    handleRemoveCluster() {
      // 收集选中的集群名称
      const clusterNames = []
      this.checkSelectName.forEach((isSelected, index) => {
        if (isSelected) {
          clusterNames.push(this.clusterView[index].cluster_name)
        }
      })

      if (clusterNames.length === 0) {
        this.$message.warning('请先选择要移除的集群')
        return
      }

      // 检查是否包含本地集群
      const hasLocalCluster = clusterNames.indexOf(this.localClusterName) > -1

      if (clusterNames.length === 1 && hasLocalCluster) {
        // 只选了本地集群
        this.$message.warning('本地集群不支持移除！')
        return
      }

      let confirmMessage = ''
      let clustersToRemove = [...clusterNames]

      if (clusterNames.length > 1 && hasLocalCluster) {
        // 多选且包含本地集群
        confirmMessage = '本地集群不支持移除，是否在集群列表中移除其他集群？'
        // 从待移除列表中排除本地集群
        clustersToRemove = clusterNames.filter((name) => name !== this.localClusterName)
      } else {
        // 不包含本地集群
        confirmMessage = '是否在集群列表中移除集群？'
      }

      // 显示确认对话框
      this.$confirm(confirmMessage, '移除集群', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
        closeOnClickModal: false,
        beforeClose: (action, instance, done) => {
          if (action === 'confirm') {
            // 开启按钮加载状态
            instance.confirmButtonLoading = true

            // 调用API
            removeCluster({ cluster_name: clustersToRemove })
              .then((res) => {
                instance.confirmButtonLoading = false
                if (res.data.action) {
                  // 检查是否有失败的集群
                  if (res.data.faild_cluster && res.data.faild_cluster.length > 0) {
                    // 部分失败
                    this.$message.error(`移除${res.data.faild_cluster}集群失败！`)
                  } else {
                    // 全部成功
                    this.$message.success('移除集群成功！')
                  }
                } else {
                  this.$message.error(res.data.error || '移除集群失败！')
                }
                // 刷新列表
                this.clusterViewDataInit()
                // 清空选中状态
                this.checkSelectName = []
                done()
              })
              .catch((err) => {
                instance.confirmButtonLoading = false
                console.error('移除集群失败:', err)
                this.$message.error('移除集群失败！')
                done()
              })
          } else {
            done()
          }
        },
      }).catch(() => {
        // 用户取消操作
      })
    },
  },
}
</script>

<style scoped lang="scss">
.view {
  background-color: #ffffff;
  height: 100vh;
}

.view-header {
  height: 60px;
  line-height: 60px;
  background-color: #f6f8fd;
  display: flex;
  justify-content: space-between;
  border-bottom: 2px solid #e4eaf9;

  .view-header_left {
    color: #000000a6;
    font-size: 18px;
    margin-left: 20px;
  }

  .view-header_right {
    display: flex;
    margin-right: 20px;
    align-items: center;

    .view-header_right__search {
      width: 200px;
      margin-right: 10px;
    }

    .view-header_right__sort {
      width: 150px;
      margin-right: 10px;
    }

    .view-header_right__btn {
      margin-right: 10px;
    }
  }
}

.view-content_none {
  text-align: center;
  margin-top: 60px;
  font-size: 14px;
  line-height: 1.5rem;

  img {
    width: 200px;
  }

  .none-btn {
    margin-top: 10px;
  }
}

.view-content_show {
  padding: 20px;

  .view-card {
    margin-bottom: 10px;
    padding-right: 10px;
    display: inline-block;
    width: 50%;
  }

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 14px;
  }

  .card-header_text {
    display: flex;
    align-items: center;

    span {
      margin-left: 8px;
    }
  }

  .card-content {
    display: flex;
    font-size: 14px;
  }

  .card-content-status-title {
    font-weight: 600;
  }

  .card-content-node {
    flex: 1 1 0%;
    flex-direction: row;
  }

  .card-content-rsc {
    flex: 5 1 0%;
    flex-direction: row;
    margin-left: 20px;
  }

  .card-content-status {
    display: flex;

    .card-content-status-cnt {
      flex-direction: column;
      margin-right: 20px;
      line-height: 1.5rem;
      margin-top: 10px;
      text-align: center;
    }
  }
}
</style>
